package com.dz.lm.service.usersend.impl;

import com.dz.lm.common.dto.PageDto;
import com.dz.lm.common.dto.UserProductDTO;
import com.dz.lm.common.dto.UserSendDTO;
import com.dz.lm.common.exception.DaoException;
import com.dz.lm.common.exception.ServiceException;
import com.dz.lm.common.util.DzCache;
import com.dz.lm.common.util.JPushUtils;
import com.dz.lm.common.util.StringUtil;
import com.dz.lm.common.utils.DateUtil;
import com.dz.lm.dao.account.write.AccountDao;
import com.dz.lm.dao.appLogin.read.AppLoginDao;
import com.dz.lm.dao.order.write.OrderDao;
import com.dz.lm.dao.usersend.write.UserSendDao;
import com.dz.lm.domain.order.Order;
import com.dz.lm.domain.userproduct.UserProduct;
import com.dz.lm.domain.userproduct.UserProductExample;
import com.dz.lm.domain.usersend.UserSend;
import com.dz.lm.domain.usersend.UserSendExample;
import com.dz.lm.service.pay.WxPayService;
import com.dz.lm.service.reminder.ReminderService;
import com.dz.lm.service.useragent.UserAgentService;
import com.dz.lm.service.userapply.impl.UserApplyServiceImpl;
import com.dz.lm.service.userproduct.UserProductService;
import com.dz.lm.service.usersend.UserSendService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * @version 1.8;
 * @author: LDY;
 * @Description;
 * @Date: Created in 2020/3/8 17:36;
 */
@Service("userSendService")
public class UserSendServiceImpl implements UserSendService {
    @Resource(name = "readUserProductDao")
    private com.dz.lm.dao.userproduct.read.UserProductDao readUserProductDao;
    @Resource(name = "writeUserSendDao")
    private UserSendDao writeUserSendDao;
    @Resource(name = "readUserSendDao")
    private com.dz.lm.dao.usersend.read.UserSendDao readUserSendDao;
    @Autowired
    private ReminderService reminderService;
    @Resource(name = "readAppLoginDao")
    private AppLoginDao rAppLoginDao;
    @Resource
    private com.dz.lm.dao.account.read.AccountDao readAccountDao;
    @Autowired
    private UserProductService userProductService;
    @Resource
    private AccountDao writeAccountDao;
    @Resource
    private OrderDao writeOrderDao;
    @Autowired
    private UserAgentService userAgentService;
    @Autowired
    private WxPayService wxPayService;
    @Resource(name = "readLoginLogDao")
    private com.dz.lm.dao.log.read.LoginLogDao loginLogDao;
    public Logger logger = LogManager.getLogger(getClass());
    @Transactional
    @Override
    public int add(int userId, int sendUid, String remark, int productId, double fee, String platform) throws ServiceException {
        int ret = 0;
        //判断是否已邀请，并且未处理的状态
        UserSendExample ex = new UserSendExample();
        UserSendExample.Criteria cr = ex.createCriteria();
        cr.andUserIdEqualTo(userId);
        cr.andSendUidEqualTo(sendUid);
        cr.andProductIdEqualTo(productId);
        cr.andStatusEqualTo(0);//发送状态
        try {
            List<UserSend> list = readUserSendDao.selectByExample(ex);
            if(list!=null&&list.size()>0){
                return  -998;
            }
            //判断有没有代理该产品
            UserProductExample productExample = new UserProductExample();
            UserProductExample.Criteria criteria = productExample.createCriteria();
            criteria.andSuperIdEqualTo(productId);
            criteria.andUserIdEqualTo(sendUid);
            criteria.andSourceEqualTo(userId);
            criteria.andProductTypeEqualTo(2);
            List<UserProduct> userProducts = readUserProductDao.selectByExample(productExample);
            if(userProducts !=null && userProducts.size() > 0){
                return  -997;
            }
        } catch (DaoException e) {
            e.printStackTrace();
        }
        UserSendExample example = new UserSendExample();
        UserSend send = new UserSend();
        send.setUserId(userId);
        send.setSendUid(sendUid);
        send.setRemark(remark);
        send.setProductId(productId);
        try {
            send.setCreateTime(com.smartlbs.util.DateUtil.getNowDateTimeString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        send.setFee(fee); //小费，在支付成功的时候填充
        if(fee>0){
            send.setStatus(-1);
        }else {
            send.setStatus(0);

        }
        try {
            ret = writeUserSendDao.insertSelective(send);
            if (ret > 0) { //push
                ret=send.getSendId();
                Map<String, Object> insertParam = new HashMap<String, Object>();
                insertParam.put("userId", sendUid);
                insertParam.put("platform", platform);
                insertParam.put("type", 1);//邀请代理

                Runnable runable = new UserSendServiceImpl.AsyncThread(insertParam);
                runable.run();

            }
        } catch (DaoException e) {


        }
        return ret;
    }
    @Override
    @Transactional
    public int handle(int sendId, int status, String platform) throws ServiceException {
        int ret = 0;
        try {
            UserSend send = new UserSend();
            send.setSendId(sendId);
            send.setStatus(status);
            int i = writeUserSendDao.updateByPrimaryKeySelective(send);
            if (i > 0) {
                ret = 1;
                UserSend userSend = readUserSendDao.selectByPrimaryKey(sendId);
                if (status == 1) { //接收代理 生成代理数据  更改账户
                     userAgentService.add(userSend.getSendUid(), userSend.getProductId(),true,"",false,"","",-1,-1,"");
                    if (userSend.getFee() > 0 && userSend.getStatus() >-1) {
                        Map userInfo = new HashMap();
                        //代理人账户
                        userInfo.put("userId", userSend.getSendUid());
                        Map<String, Object> Uaccount = readAccountDao.qryAccountInfoByUserId(userInfo);
                        userInfo.clear();
                        //原生产品人账户
                        userInfo.put("userId", userSend.getUserId());
                        Map<String, Object> Saccount = readAccountDao.qryAccountInfoByUserId(userInfo);

                        BigDecimal fee = new BigDecimal(userSend.getFee());
                        BigDecimal amount = new BigDecimal(Uaccount.get("amount").toString());
                        BigDecimal nowAmount = amount.add(fee);
                        BigDecimal cashAmount = new BigDecimal(Uaccount.get("cashAmount").toString());
                        BigDecimal nowCashAmount = cashAmount.add(fee);
                        //受邀人账户流水
                        //代理人账户流水
                        Order order = new Order();
                        String orderId = getOrderId();
                        order.setOrderId(orderId);
                        order.setUserId(Integer.parseInt(Uaccount.get("userId").toString()));
                        order.setAccountId(Integer.valueOf(Uaccount.get("accountId").toString()));
                        order.setAmount(userSend.getFee());
                        order.setGatherAccountId(Integer.valueOf(Saccount.get("accountId").toString()));
                        order.setGatherUserId(Integer.parseInt(Saccount.get("userId").toString()));
                        order.setOrderType("6");//代理费 收入
                        order.setPayType("3");//账户
                        order.setState("13");//冲入
                        writeOrderDao.addOrder(order);
                        //远产品人 账单流水
                      /*  Order ordery = new Order();
                        String orderIdy = getOrderId();
                        ordery.setOrderId(orderIdy);
                        ordery.setUserId(Integer.parseInt(Saccount.get("userId").toString()));
                        ordery.setAccountId(Integer.valueOf(Saccount.get("accountId").toString()));
                        ordery.setAmount(userSend.getFee());
                        ordery.setGatherAccountId(Integer.valueOf(Uaccount.get("accountId").toString()));
                        ordery.setGatherUserId(Integer.parseInt(Uaccount.get("userId").toString()));
                        ordery.setOrderType("4");//代理费 支出
                        ordery.setPayType("3");//账户
                        ordery.setState("23");//已完成
                        writeOrderDao.addOrder(ordery);*/
                        //更新账户
                        Uaccount.put("amount", nowAmount);
                        Uaccount.put("cash_amount", nowCashAmount);
                        writeAccountDao.updateAccount(Uaccount);
                    }
                } else if (status == 2 && userSend.getStatus() >-1) { //取消
                    Map userInfo = new HashMap();

                    //邀请人账户
                    userInfo.put("userId", userSend.getUserId());
                    Map<String, Object> Saccount = readAccountDao.qryAccountInfoByUserId(userInfo);
                    BigDecimal fee = new BigDecimal(userSend.getFee());
                    BigDecimal amount = new BigDecimal(Saccount.get("amount").toString());
                    BigDecimal nowAmount = amount.add(fee);
                    BigDecimal cashAmount = new BigDecimal(Saccount.get("cashAmount").toString());
                    BigDecimal nowCashAmount = cashAmount.add(fee);
                    Order order = new Order();
                    String orderId = getOrderId();
                    order.setOrderId(orderId);
                    order.setUserId(Integer.parseInt(Saccount.get("userId").toString()));
                    order.setAccountId(Integer.valueOf(Saccount.get("accountId").toString()));
                    order.setAmount(userSend.getFee());
                    order.setGatherAccountId(Integer.valueOf(Saccount.get("accountId").toString()));
                    order.setGatherUserId(Integer.parseInt(Saccount.get("userId").toString()));
                    order.setOrderType("4");//代理费
                    order.setPayType("3");//账户
                    order.setState("13");//已完成
                    writeOrderDao.addOrder(order);
                    //更新账户
                    Saccount.put("amount", nowAmount);
                    Saccount.put("cash_amount", nowCashAmount);
                    writeAccountDao.updateAccount(Saccount);
                }
                if(ret > 0){
                    ret=send.getSendId();
                    Map<String, Object> insertParam = new HashMap<String, Object>();
                    insertParam.put("userId", userSend.getUserId());
                    insertParam.put("platform", platform);
                    insertParam.put("type", 2);//邀请处理

                    Runnable runable = new UserSendServiceImpl.AsyncThread(insertParam);
                    runable.run();
                }
            }

        } catch (DaoException e) {


        }
        return ret;
    }
    @Transactional
    @Override
    public PageDto query(int pageNum, int rows, int userId, int sendUid, int product, int status) throws ServiceException {
        PageDto pageDto = new PageDto();
        PageHelper.startPage(pageNum, rows);
        UserSendExample ex = new UserSendExample();
        UserSendExample.Criteria cr = ex.createCriteria();
        if (userId > 0) {
            cr.andUserIdEqualTo(userId);
        }
        if (sendUid > 0) {
            cr.andSendUidEqualTo(sendUid);
        }
        cr.andStatusEqualTo(status);
        if (product > 0) {
            cr.andProductIdEqualTo(product);
        }
        try {
            List<UserSend> list = readUserSendDao.selectByExample(ex);
            if (list != null && list.size() > 0) {
                PageInfo pageInfo = new PageInfo(list);
                List<UserSendDTO> dtos = new ArrayList();
                for (UserSend send : list) {
                    UserSendDTO dto = new UserSendDTO();
                    BeanUtils.copyProperties(send, dto);
                    setExt(dto);
                    dtos.add(dto);
                }
                pageDto.setInfo(pageInfo);
                pageDto.setList(dtos);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageDto;
    }

    private void setExt(UserSendDTO dto) throws Exception {
        UserProductDTO detail = userProductService.getDetail(0, dto.getProductId(), false);
        if (detail != null) {
            dto.setProduct(detail);
        }
        Map p1 = new HashMap();
        p1.put("userId", dto.getUserId());
        Map user = rAppLoginDao.qryUserInfoByUserId(p1);
        if (user != null) {
            dto.setUser(user);
        }
    }

    /**
     * 生产订单ID
     */
    private String getOrderId() {
        String orderId = "";
        @SuppressWarnings("unchecked")
        List<String> orderIdList = (List<String>) DzCache.getCacheCode("orderId");
        if (orderIdList != null && orderIdList.get(0) != null) {
            orderId = orderIdList.get(0);
            orderIdList.remove(0);
        } else {
            long todayMaxorderId = DzCache.getCacheCode("todayMaxorderId") == null ? 0l : (long) DzCache.getCacheCode("todayMaxorderId");
            long maxId = todayMaxorderId + 100;
            DzCache.setCacheCode("todayMaxorderId", maxId);
            orderIdList = new ArrayList<String>();
            String strTime = DateUtil.getTimeStrFormat(new Date());
            String suffix = "00000000";
            for (long i = todayMaxorderId + 1; i < maxId + 1; i++) {
                suffix = suffix + "" + i;
                suffix = suffix.substring(suffix.length() - 8, suffix.length());
                orderIdList.add(strTime + "" + suffix);
            }
            orderId = orderIdList.get(0);
            orderIdList.remove(0);
            DzCache.setCacheCode("orderId", orderIdList);
        }
        return orderId;
    }
    @Transactional
    @Override
    public int update(UserSend userSend) throws ServiceException {
        int ret =0;
        try {
            ret =writeUserSendDao.updateByPrimaryKeySelective(userSend);
        } catch (DaoException e) {
            e.printStackTrace();
        }
        return ret;
    }
    public class AsyncThread implements Runnable {
        private Map<String, Object> param;

        AsyncThread(Map<String, Object> param) {
            this.param = param;
        }

        @Override
        public void run() {
            try {
                pushMessage(param);
            } catch (ServiceException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 消息推送
     */
    private void pushMessage(Map<String, Object> param) throws ServiceException {
        Map<String, Object> pushInfo = null;
        Map<String, String> map_jp = Maps.newHashMap();
        try {
            pushInfo = loginLogDao.qryPushIdByUserId(param);
            if (pushInfo == null || pushInfo.isEmpty() || pushInfo.get("pushId") == null || "".equals(pushInfo.get("pushId"))) {
                return;
            }
            String pushTitle = "";
            String pushContent = "";
            int type = StringUtil.getInt(param.get("type"), 0);
            if( type== 1 ){ //1产品申请
                pushTitle = "【微介】代理邀请提醒";
                pushContent = "您有代理邀请，请注意查收";
            }
            if(type == 2){ //产品处理
                pushTitle = "【微介】代理邀请处理提醒";
                pushContent = "您有代理邀请已处理，请注意查收";
            }
            // 推送
            if ("Android".equals(param.get("platform")) || "wexin".equals(param.get("platform"))) {
                // jpush
                String deviceAndro = pushInfo.get("pushId") == null ? "" : pushInfo.get("pushId").toString();
                //push消息
//                JPushUtils.pushAndroidMessageByRegistrationID(pushTitle, pushContent, deviceAndro);
                JPushUtils.pushAndroidNotificationByRegistrationID(pushTitle, pushContent, new HashMap(), deviceAndro);
            } else {
                if(param.get("IOS") != null){
                    String[] deviceIos = param.get("IOS").toString().split(",");
                    JPushUtils.pushIosNotificationByRegistrationID(pushContent, map_jp, deviceIos);
                }
            }
            logger.info("消息推送成功");
        } catch (DaoException e) {
            logger.info("消息推送失败");
            throw new ServiceException(e.getCause());
        }
    }
    @Transactional
    @Override
    public int queryCount(int userId, int sendUid, int productId, int status) throws ServiceException {
        int count =0;
        UserSendExample ex = new UserSendExample();
        UserSendExample.Criteria cr = ex.createCriteria();
        if(userId > 0){
            cr.andUserIdEqualTo(userId);
        }
        if(sendUid > 0){
            cr.andSendUidEqualTo(sendUid);
        }
        if(productId > 0){
            cr.andProductIdEqualTo(productId);
        }
        if(status > -1){
            cr.andStatusEqualTo(status);
        }
        try {
            count =  readUserSendDao.selectCount(ex);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return 0;
    }
}
